package edu.nju.mutest.mutator;

import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.expr.BinaryExpr;
import com.github.javaparser.ast.expr.BooleanLiteralExpr;
import com.github.javaparser.ast.expr.Expression;
import edu.nju.mutest.util.CollectorUtil;
import edu.nju.mutest.visitor.collector.BinaryExprCollector;

import java.util.List;

import static com.github.javaparser.ast.expr.BinaryExpr.Operator.*;

public class RelationalOperationReplacementMutator extends AbstractMutator{

    private final List<BinaryExpr.Operator> targetOps = List.of(
            EQUALS, NOT_EQUALS, LESS, GREATER, LESS_EQUALS, GREATER_EQUALS
    );

    public RelationalOperationReplacementMutator(CompilationUnit cu) {
        super(cu);
    }

    @Override
    public List<CompilationUnit> mutate() {
        if (this.mutPoints == null)
            mutPoints = CollectorUtil.collect(new BinaryExprCollector(), this.origCU);

        for (Expression mp : mutPoints) {
            generateMutantsForRelationalBinaryExpr((BinaryExpr) mp, targetOps);
        }
        return mutants;
    }

    /**
     * @see AbstractMutator#generateMutantsForBinaryExpr(BinaryExpr, List) 
     */
    protected void generateMutantsForRelationalBinaryExpr(BinaryExpr be, List<BinaryExpr.Operator> ops) {
        if (ops.contains(be.getOperator())) {
            for (BinaryExpr.Operator targetOp : ops) {
                if (be.getOperator() != targetOp) {
                    replaceBinaryOperator(be, targetOp);
                }
            }
            replaceNode(be, new BooleanLiteralExpr(true));
            replaceNode(be, new BooleanLiteralExpr(false));
        }
    }
}
